package com.newegg.sshd;

import java.io.IOException;
import org.apache.sshd.common.util.threads.ThreadUtils;
import org.apache.sshd.server.channel.ChannelSession;
import org.apache.sshd.server.command.AbstractCommandSupport;
import org.apache.sshd.server.session.ServerSession;
import org.jline.reader.LineReader;
import org.jline.reader.LineReaderBuilder;
import org.jline.terminal.Terminal;
import org.jline.terminal.TerminalBuilder;
import org.slf4j.Logger;

import com.newegg.sshd.util.IPHelp;

public class BashCommand extends AbstractCommandSupport {
	static Logger logger = org.slf4j.LoggerFactory.getLogger(BashCommand.class);
	ChannelSession channel;
	Terminal terminal;

	public BashCommand(ChannelSession channel) {
		super("SSH", ThreadUtils.newSingleThreadExecutor(channel.getSession().getUsername()));
		this.channel = channel;
	}

	@Override
	public void run() {
		try {
			terminal = TerminalBuilder.builder().system(false).streams(in, out).build();
			writeBanner();
			LineReader reader = LineReaderBuilder.builder().terminal(terminal).build();
            String cmd;
            while((cmd = reader.readLine(getBreaks())) != null) {
            	ServerSession session = channel.getSession();
            	logger.info("用户[" + session.getClientAddress().toString() + "]执行命令：" + cmd);
            	String commandLine = cmd;
				if (commandLine.indexOf(" ") != -1) {
					cmd = commandLine.substring(0, commandLine.indexOf(" "));
					commandLine = commandLine.substring(commandLine.indexOf(" ") + 1);
				}
				commandLine = commandLine.replaceFirst(cmd, "");
				AbstractCommand bean = loadPlugin(upperFirstLatter(cmd), commandLine);
				if (bean == null) {
					echo("-bash: " + cmd + ": command not found");
					continue;
				}
				if (bean.help) {
					echo(bean.help());
				} else {
					echo(bean.run());
				}
				bean = null;
            }
		} catch (IOException e) {
			e.printStackTrace();
			callback.onExit(0, e.getMessage());
		}
	}

	private void echo(String line) {
		if(terminal == null) { return; }
		terminal.writer().println(line);
        terminal.flush();
	}

	private void writeBanner() {
    	echo("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@");
    	echo("@                                                         @"); 
    	echo("@                         WELCOME                         @"); 
    	echo("@                                                         @"); 
    	echo("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@");
    	echo("");
	}
	
    private String getBreaks() {
    	String name = this.serverSession.getUsername();
		String hostname = IPHelp.getHostname();
		return "[" + name + "@" + hostname + " ~]# ";
	}

	@SuppressWarnings("unchecked")
	private <T extends AbstractCommand> T loadPlugin(String cmd, String command) {
    	try {
    		Class<T> clazz = (Class<T>) Class.forName("com.newegg.sshd.command." + cmd);
    		T bean = AbstractCommand.getInstance(clazz, command);
    		bean.callback = callback;
    		bean.channel = channel;
    		bean.cmdRunner = cmdRunner;
    		bean.terminal = terminal;
    		bean.environment = environment;
    		return bean;
		}catch (ClassNotFoundException e) {
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}
	
	public String upperFirstLatter(String letter){
        char[] chars = letter.toCharArray();
        if(chars[0]>='a' && chars[0]<='z'){
            chars[0] = (char) (chars[0]-32);
        }
        return new String(chars);
    }
	
	@Override
	public void destroy(ChannelSession channel) throws Exception {
		if(terminal != null) {
			terminal.close();
		}
		super.destroy(channel);
	}
	
}
